package com.b2.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.b2.constant.MessageConstant;
import com.b2.context.BaseContext;
import com.b2.exception.BaseException;
import com.b2.exception.LoginFailedException;
import com.b2.mapper.*;
import com.b2.pojo.dto.UserLoginDTO;
import com.b2.pojo.dto.UserWebLoginDTO;
import com.b2.pojo.dto.WebWxRegiestDto;
import com.b2.pojo.entity.*;
import com.b2.properties.WeChatProperties;
import com.b2.result.Result;
import com.b2.service.UserService;
import com.b2.utils.HttpClientUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

import static com.b2.constant.JwtClaimsConstant.INVITE_CODE;

/**
* @author 悦神
* @description 针对表【user】的数据库操作Service实现
* @createDate 2024-04-23 15:38:16
*/
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
    implements UserService {
    public static final String
            wx_login = "https://api.weixin.qq.com/sns/jscode2session";
    @Autowired
    ParentMapper parentMapper;
    @Autowired
    UserMapper userMapper;
    @Autowired
    DirectorMapper directorMapper;
    @Autowired
    TeacherMapper teacherMapper;
    @Autowired
    AdminMapper adminMapper;
    @Autowired
    WeChatProperties weChatProperties;

    @Override
    @Transactional
    public User login(UserLoginDTO userLoginDTO) {
        Map<String, String> map = new HashMap<>();
        map.put("appid", weChatProperties.getAppid());
        map.put("secret", weChatProperties.getSecret());
        map.put("js_code", userLoginDTO.getCode());
        map.put("grant_type", "authorization_code");
        String s = HttpClientUtil.doGet(wx_login, map);//得到一个json对象
        JSONObject jsonObject = JSON.parseObject(s);
        String openid = jsonObject.getString("openid");
        if (openid == null) {
            throw new LoginFailedException(MessageConstant.LOGIN_FAILED);
        }
        LambdaQueryWrapper<User> objectLambdaQueryWrapper = new LambdaQueryWrapper<>();
        objectLambdaQueryWrapper.eq(User::getOpenid, openid);
        User user = userMapper.selectOne(objectLambdaQueryWrapper);
        if (user == null) {
            user = new User();
            user.setOpenid(openid);
            user.setCreatetime(LocalDateTime.now());
            userMapper.insert(user);
        }
        return user;
    }

    @Override
    @Transactional
    public void addphone(String phone) {
        Long currentId = BaseContext.getCurrentId();
        User user = userMapper.selectById(currentId);
        user.setPhone(phone);
        userMapper.updateById(user);
    }

    @Override
    @Transactional
    public Result identificate(String id) {
        if (id.equals("0")) {
            Long currentId = BaseContext.getCurrentId();
            User user = userMapper.selectById(currentId);
            String phone = user.getPhone();
            LambdaQueryWrapper<Director> o = new LambdaQueryWrapper<>();
            o.eq(Director::getPhone, phone);
            Director director = directorMapper.selectOne(o);
            if (director != null) {
                return Result.success(director);
            } else {
                return Result.error(MessageConstant.IDENTIFICATE_FAILED);
            }
        } else if (id.equals("1")) {
            Long currentId = BaseContext.getCurrentId();
            User user = userMapper.selectById(currentId);
            String phone = user.getPhone();
            LambdaQueryWrapper<Teacher> o = new LambdaQueryWrapper<>();
            o.eq(Teacher::getPhone, phone);
            Teacher teacher = teacherMapper.selectOne(o);
            if (teacher != null) {
                return Result.success(teacher);
            } else {
                return Result.error(MessageConstant.IDENTIFICATE_FAILED);
            }
        } else if (id.equals("2")) {
            Long currentId = BaseContext.getCurrentId();
            User user = userMapper.selectById(currentId);
            String phone = user.getPhone();
            LambdaQueryWrapper<Parent> o = new LambdaQueryWrapper<>();
            o.eq(Parent::getPhone, phone);
            Parent parent = parentMapper.selectOne(o);
            if (parent != null) {
                return Result.success(parent);
            } else {
                return Result.error(MessageConstant.IDENTIFICATE_FAILED);
            }

        } else if (id.equals("3")) {
            return Result.success();
        } else if (id.equals("100")) {
            Long currentId = BaseContext.getCurrentId();
            User user = userMapper.selectById(currentId);
            String phone = user.getPhone();
            LambdaQueryWrapper<Admin> adminLambdaQueryWrapper = new LambdaQueryWrapper<>();
            adminLambdaQueryWrapper.eq(Admin::getPhone, phone);
            Admin admin = adminMapper.selectOne(adminLambdaQueryWrapper);
            if (admin != null) {
                return Result.success(admin);
            } else {
                return Result.error(MessageConstant.IDENTIFICATE_FAILED);
            }
        } else {
            return Result.error(MessageConstant.VOID);
        }
    }

    /**
     * web端登录
     *
     * @param userLoginDTO
     * @return
     */
    @Override
    public User webLogin(UserWebLoginDTO userLoginDTO) {
        //1. 校验参数
        String phone = userLoginDTO.getPhone();
        String password = userLoginDTO.getPassword();
        //1.校验参数
        if (StringUtils.isAnyEmpty(phone, password)) {
            throw new BaseException("参数为空");
        }

        if (phone.length() != 11) {
            throw new BaseException("手机号格式错误");
        }
        //  5. 账户不包含特殊字符
        // 匹配由数字、小写字母、大写字母组成的字符串,且字符串的长度至少为1个字符
        String pattern = "[0-9a-zA-Z]+";
        if (!phone.matches(pattern)) {
            throw new BaseException("用户账号包含特殊字符");
        }
        //加密
        password = DigestUtils.md5DigestAsHex(password.getBytes());

        //2. 查询用户信息
        User user = userMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getPhone, phone));
        //3. 判断用户是否存在-如果存在就不能创建
        if (user == null) {
            throw new BaseException("用户不存在");
        }
        //4 存在 判断密码是否正确
        if (!password.equals(user.getPassword())) {
            throw new BaseException("密码错误");
        }
        return user;
    }

    /**
     * web端注册
     *
     * @param webWxRegiestDto
     * @return
     */
    @Override
    public User webRegitse(WebWxRegiestDto webWxRegiestDto) {
        String phone = webWxRegiestDto.getPhone();
        String userPassword = webWxRegiestDto.getUserPassword();
        String checkPassword = webWxRegiestDto.getCheckPassword();
        //1.校验参数
        if (StringUtils.isAnyEmpty(phone, userPassword, checkPassword)) {
            throw new BaseException("参数为空");
        }
        if (!userPassword.equals(checkPassword)) {
            throw new BaseException("密码不一致");
        }

        if (phone.length() != 11) {
            throw new BaseException("手机号格式错误");
        }
        //  5. 账户不包含特殊字符
        // 匹配由数字、小写字母、大写字母组成的字符串,且字符串的长度至少为1个字符
        String pattern = "[0-9a-zA-Z]+";
        if (!phone.matches(pattern) && !userPassword.matches(pattern)) {
            throw new BaseException("用户账号或包含特殊字符");
        }
        //加密
        userPassword = DigestUtils.md5DigestAsHex(userPassword.getBytes());
        //2.查询用户信息
        User user = userMapper.selectOne(Wrappers.<User>lambdaQuery().eq(User::getPhone, phone));
        if (user != null) {
            throw new BaseException("用户已存在");
        }
        //3. 创建用户
        user = new User();
        user.setPhone(phone);
        user.setPassword(userPassword);
        user.setCreatetime(LocalDateTime.now());
        int insert = userMapper.insert(user);
        if (insert == 0) {
            throw new BaseException("注册失败");
        }
        return user;
    }


}





